package com.ht.pms.core.handler;

import java.text.SimpleDateFormat;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ht.pms.core.common.constant.SalaryConstants;
import com.ht.pms.core.common.constant.SalaryTemplateTableEnum;
import com.ht.pms.core.common.exception.ExcelParseException;
import com.ht.pms.core.common.exception.ParamException;
import com.ht.pms.core.dao.SalaryBusinessDictDao;
import com.ht.pms.core.dao.SalaryTemplateDao;
import com.ht.pms.core.dao.SalaryTemplateDetailDao;
import com.ht.pms.core.dao.SalaryUploadFileDao;
import com.ht.pms.core.dto.ReturnCodeEnum;
import com.ht.pms.core.dto.dict.DictParamsDto;
import com.ht.pms.core.dto.dict.DictParamsReq;
import com.ht.pms.core.dto.poi.SalaryUploadParam;
import com.ht.pms.core.dto.tempalte.Template;
import com.ht.pms.core.dto.tempalte.TemplateDetailParam;
import com.ht.pms.core.dto.tempalte.TemplateDetailReq;
import com.ht.pms.core.dto.upload.UploadFile;
import com.ht.pms.core.dto.upload.UploadFileExcelVo;
import com.ht.ussp.client.dto.LoginInfoDto;

@Service
public class SalaryValidateDataHandler {
	private static final Logger LOGGER = LoggerFactory.getLogger(SalaryValidateDataHandler.class);

	/** '1 考勤模板 2 工资模板 3 基础模板 4 发送-考勤 5 发送-工资' */
	private static final int SALARY_UPLOAD_TYPE_ATTENDANCE = 1;
	private static final int SALARY_UPLOAD_TYPE_SALARY = 2;
	/** '1 考勤模板 2 工资模板 3 基础模板 4 发送-考勤 5 发送-工资' */
	private static final int SALARY_UPLOAD_TYPE_BASE = 3;

	@Autowired
	private SalaryTemplateDao salaryTemplateDao;

	@Autowired
	private SalaryUploadFileDao salaryUploadFileDao;

	@Autowired
	private SalaryTemplateDetailDao salaryTemplateDetailDao;

	@Autowired
	private SalaryBusinessDictDao salaryBusinessDictDao;
	

	public UploadFileExcelVo validateSalaryUploadParam(SalaryUploadParam req) {
		UploadFileExcelVo vo = new UploadFileExcelVo();
		Integer fileId = null;
		String batchCode = null;
		// 参数校验
		if (req == null) {
			LOGGER.error("[导入基础数据] 请求参数基本信息为空！");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(),
					ReturnCodeEnum.ERROR_PARAM.getCodeDesc());
		}
		if (req.getFile() == null) {
			LOGGER.error("[导入基础数据] 请求参数导入文件为空！");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(),
					ReturnCodeEnum.ERROR_PARAM.getCodeDesc() + ": file");
		}

		if (req.getFileId() != null) {// 上传的是错误数据，通过fileId查询
			UploadFile file = salaryUploadFileDao.selectUploadFileByFileId(req.getFileId());
			if (file == null) {
				LOGGER.error("[导入错误数据] 导入原文件不存在！");
				throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(), "导入原文件不存在！");
			}
			fileId = file.getFileId();
			batchCode = file.getBatchCode();
			Template template = salaryTemplateDao.selectTemplateByTemplateCode(file.getTemplateCode());
			vo.setTemplateType(template.getTemplateType());
			vo.setTemplateCode(file.getTemplateCode());
			
		} else { // 每次都是新增上传
			if (req.getTimeYearMonth() == null) {
				LOGGER.error("[导入基础数据] 请求参数日期为空！");
				throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(),
						ReturnCodeEnum.ERROR_PARAM.getCodeDesc() + ": YearMonth");
			}
			String time = new SimpleDateFormat("yyyy-MM").format(req.getTimeYearMonth());

			Template template = salaryTemplateDao.selectTemplateByTemplateCode(req.getTemplateCode());
			if (template != null) {
				if (template.getTemplateType() == SALARY_UPLOAD_TYPE_ATTENDANCE
						|| template.getTemplateType() == SALARY_UPLOAD_TYPE_SALARY
						|| template.getTemplateType() == SALARY_UPLOAD_TYPE_BASE) {
					vo.setTemplateType(template.getTemplateType());
				} else {
					LOGGER.error("[文件上传] 请选择数据模板 ");
					throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(), "请选择数据模板");
				}

			}

			UploadFile uploadFile2 = validateSalaryUploadFile(req);

			UploadFile uploadFile = new UploadFile();
			if (uploadFile2 != null) {
				// 该模板数据在当月已存在
				batchCode = uploadFile2.getBatchCode();
				uploadFile.setBatchCode(batchCode);

				String fileCodeOld = uploadFile2.getFileCode();
				String[] splitFileCode = fileCodeOld.split("_");
				
				uploadFile.setFileCode(splitFileCode[0] +"_"+ (Integer.valueOf(splitFileCode[1]) + 1));
				
				// 修改 uploadFile2 状态失效
				uploadFile2.setIsDel(SalaryConstants.SALARY_YES);
				salaryUploadFileDao.updateSalaryFileState(uploadFile2);
				uploadFile2.setState(SalaryConstants.SALARY_NO);
				salaryBusinessDictDao.updateSalaryDictState(uploadFile2, SalaryTemplateTableEnum.getByTemplateType(template.getTemplateType()).getRelationTable());
			} else {
				batchCode = SalaryTemplateTableEnum.getByTemplateType(template.getTemplateType()).getBatchCodePrefix()
						+ time.replace("-", "");

				uploadFile.setBatchCode(batchCode);
				uploadFile.setFileCode(batchCode + "_1");
			}

			uploadFile.setFileName(req.getFileName());
			uploadFile.setTemplateCode(req.getTemplateCode());
			uploadFile.setState(SalaryConstants.SALARY_NO);
			uploadFile.setTime(time);
			uploadFile.setImportUserId(req.getUserId());
			uploadFile.setImportUserName(req.getUserName());
			// 插入小批次
			fileId = salaryUploadFileDao.insertSalaryFile(uploadFile);
			vo.setTemplateCode(req.getTemplateCode());
		}

		vo.setBatchCode(batchCode);
		vo.setFileId(fileId);
		return vo;
	}

	/**
	 * 校验表头字段与模板字段是否一致返回 字段列表用于校验每一行数据
	 * 
	 * @param integer
	 * @param titles
	 * @param batchId
	 */
	public List<DictParamsDto> validateSalaryTitles(String templateCode, List<String> titles, String batchId) {
		List<DictParamsDto> dictParamsDtos = salaryTemplateDetailDao.selectDictParamsByTemplateCode(templateCode);
		if (dictParamsDtos == null || dictParamsDtos.isEmpty()) {
			LOGGER.error("[导入基础数据] 根据模板编码：[{}] 查询相应字段不存在! ", templateCode);
			throw new ExcelParseException(ReturnCodeEnum.EXCEPTION.getReturnCode(),
					String.format("根据模板编码[%s]查询模板字段为空!", templateCode));
		}
		
		for (String title : titles) {
			boolean flag = false;
			for (DictParamsDto dictParamsDto : dictParamsDtos) {
				if (title.equals(dictParamsDto.getDictName())) {
					flag = true;
					break;
				}
			}
			if (!flag) {
				LOGGER.error("[导入基础数据] 表头名称：[{}] 在模板中未定义 ", title);
				throw new ExcelParseException(ReturnCodeEnum.EXCEPTION.getReturnCode(),
						String.format("表头名称[%s]在模板中未定义", title));
			}

		}
		
		for (DictParamsDto dictParamsDto : dictParamsDtos) {
			boolean flag = false;
			for (String title : titles) {
				if (title.equals(dictParamsDto.getDictName())) {
					flag = true;
				}
			}
			if (!flag) {
				LOGGER.error("[导入基础数据] 导入数据表头缺少模板字段{} ", dictParamsDto.getDictName());
				throw new ExcelParseException(ReturnCodeEnum.EXCEPTION.getReturnCode(),
						String.format("导入数据表头缺少模板字段%s", dictParamsDto.getDictName()));
			}
		}
		
		long count = titles.stream().distinct().count();
		if (count < titles.size()) {
			LOGGER.error("[导入基础数据] 批次id[{}] 表头名称有重复，请检查！ ", batchId);
			throw new ExcelParseException(ReturnCodeEnum.EXCEPTION.getReturnCode(), "表头名称有重复，请检查！");
		}

		// 检验工号存在
		if (titles.indexOf(SalaryConstants.SALARY_JOB_CODE_NAME) == -1) {
			LOGGER.error("[导入基础数据] 导入数据中 未找到工号 ");
			throw new ExcelParseException(ReturnCodeEnum.EXCEPTION.getReturnCode(), String.format("导入数据中 未找到工号！ "));
		}

		// 检验序号存在
		if (titles.indexOf(SalaryConstants.SALARY_SEQUENCE_NUMBER_NAME) == -1) {
			LOGGER.error("[导入基础数据] 导入数据中 未找到序号 ");
			throw new ExcelParseException(ReturnCodeEnum.EXCEPTION.getReturnCode(), String.format("导入数据中 未找到序号！ "));
		}

		return dictParamsDtos;
	}

	public void validateSalaryTemplateDetail(TemplateDetailReq req) {
		if (req == null) {
			LOGGER.error("[模板管理] 保存模板字段基础信息为空 ");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(), "保存模板字段基础信息为空!");
		}

		if (req.getResultFields() == null || req.getResultFields().isEmpty()) {
			LOGGER.error("[模板管理] 保存模板字段信息为空 ");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(), "保存模板字段信息为空!");
		}
	}

	public void validateSalaryTemplate(TemplateDetailParam req) {
		if (req == null) {
			LOGGER.error("[模板管理] 保存模板字段基础信息为空 ");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(), "保存模板字段基础信息为空!");
		}

		if (StringUtils.isEmpty(req.getTemplateCode())) {
			LOGGER.error("[模板管理] 保存模板编码为空 , 请先添加字段");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(), String.format("请先选择字段！"));
		}

		if (StringUtils.isEmpty(req.getTemplateName())) {
			LOGGER.error("[模板管理] 保存模板名称为空 ");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(), String.format("模板名称为空！"));
		}
	}

	public UploadFile validateSalaryUploadFile(SalaryUploadParam req) {
		// 判断模板类型
		if (StringUtils.isEmpty(req.getTemplateCode())) {
			LOGGER.error("[导入基础数据] 请求参数模板编码为空！");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(),
					ReturnCodeEnum.ERROR_PARAM.getCodeDesc() + ": templateCode");
		}
		Template template = salaryTemplateDao.selectTemplateByTemplateCode(req.getTemplateCode());
		if (template == null) {
			LOGGER.error("[文件上传] 模板不存在 ");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(), "选择模板不存在!");
		}
		if (req.getTimeYearMonth() == null) {
			LOGGER.error("[文件上传] 选择日期为空！");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(),
					ReturnCodeEnum.ERROR_PARAM.getCodeDesc() + ": YearMonth");
		}
		String time = new SimpleDateFormat("yyyy-MM").format(req.getTimeYearMonth());

		return salaryUploadFileDao.selectUploadFileByTime(time, req.getTemplateCode());

	}

	public DictParamsDto validateDictParam(DictParamsReq req) {
		DictParamsDto dto = new DictParamsDto();
		if (req == null) {
			LOGGER.error("[字段管理] 保存字段基础信息为空 ");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(), "保存字段基础信息为空!");
		}
		if (req.getDictName() == null) {
			LOGGER.error("[字段管理] 字段名称为空");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(), "字段名称为空!");
		}
		
		if (req.getDictDataType() == null) {
			LOGGER.error("[字段管理] 字段值类型为空");
			throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(), "字段值类型为空!");
		}
		
		// 判断名称是否重复
		DictParamsDto paramDto = salaryBusinessDictDao.selectDictParamByDictName(req.getDictName(), req.getDictTableName());
		
		if(StringUtils.isBlank(req.getDictCode())) {
			if (paramDto != null) {
				LOGGER.error("[字段管理] 字段名称{}已存在", req.getDictName());
				throw new ParamException(ReturnCodeEnum.ERROR_PARAM.getReturnCode(),
						String.format("字段名称%s已存在！", req.getDictName()));
			}
			dto.setDictDataDesc("varchar(45)");
		}
		
		dto.setDictName(req.getDictName());
		dto.setDictDataType(req.getDictDataType());
		dto.setDictTableName(req.getDictTableName());
		dto.setDictCode(req.getDictCode());
		return dto;
	}
	
}
